package com.jvyou.app.ds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jvyou.app.common.domain.dto.RegionDto;
import com.jvyou.app.common.domain.entity.Region;
import com.jvyou.app.common.domain.model.PageResult;
import com.jvyou.app.common.utils.orm.WrapperTool;
import com.jvyou.app.ds.mapper.RegionMapper;
import com.jvyou.app.ds.service.RegionService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * 行政区域表(Region)表服务实现类
 *
 * @author 橘柚
 * @since 2025-03-11 17:26:41
 */
@RequiredArgsConstructor
@Service("regionService")
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements RegionService {

    private final RegionMapper regionMapper;

    private QueryWrapper<Region> getWrapper(RegionDto regionDto) {
        QueryWrapper<Region> wrapper = new QueryWrapper<>();
        WrapperTool.notEmptyEq(wrapper, "province_code", regionDto.getProvinceCode());
        WrapperTool.notEmptyLike(wrapper, "province", regionDto.getProvince());
        WrapperTool.notEmptyEq(wrapper, "city_code", regionDto.getCityCode());
        WrapperTool.notEmptyLike(wrapper, "city", regionDto.getCity());
        WrapperTool.notEmptyEq(wrapper, "district_code", regionDto.getDistrictCode());
        WrapperTool.notEmptyLike(wrapper, "district", regionDto.getDistrict());
        WrapperTool.notEmptyLike(wrapper, "abbr", regionDto.getAbbr());
        return wrapper;
    }

    @Override
    public List<Region> listRegion(RegionDto regionDto) {
        return list(getWrapper(regionDto));
    }

    @Override
    public PageResult<Region> pageRegion(RegionDto regionDto) {
        Page<Region> page = new Page<>(regionDto.getCurrent(), regionDto.getPageSize());
        return PageResult.success(page(page, getWrapper(regionDto)));
    }

    @Override
    @Cacheable(value = "regin", key = "#root.methodName")
    public List<Map<String, Object>> regionTree() {
        LambdaQueryWrapper<Region> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Region::getProvinceCode, Region::getCityCode, Region::getDistrictCode);
        List<Region> regionList = list(wrapper);

        // 省份 Map（保证顺序）
        Map<String, Map<String, Object>> provinceMap = new LinkedHashMap<>();

        for (Region region : regionList) {
            String provinceName = region.getProvince();
            String cityName = region.getCity();
            String districtName = region.getDistrict();

            // 获取或创建省份节点
            Map<String, Object> provinceNode = provinceMap.computeIfAbsent(provinceName, k -> {
                Map<String, Object> node = new HashMap<>();
                node.put("value", provinceName);
                node.put("label", provinceName);
                node.put("children", new ArrayList<Map<String, Object>>());
                return node;
            });

            // 获取当前省份的城市列表
            List<Map<String, Object>> cityList = (List<Map<String, Object>>) provinceNode.get("children");

            // 查找或创建城市节点
            Map<String, Object> cityMap = cityList.stream()
                    .filter(city -> city.get("value").equals(cityName))
                    .findFirst()
                    .orElseGet(() -> {
                        Map<String, Object> newCity = new HashMap<>();
                        newCity.put("value", cityName);
                        newCity.put("label", cityName);
                        newCity.put("children", new ArrayList<Map<String, Object>>());
                        cityList.add(newCity);
                        return newCity;
                    });

            // 获取当前城市的区县列表
            List<Map<String, Object>> districtList = (List<Map<String, Object>>) cityMap.get("children");

            // 添加区县信息（保证顺序）
            Map<String, Object> districtMap = new HashMap<>();
            districtMap.put("value", districtName);
            districtMap.put("label", districtName);
            districtList.add(districtMap);
        }

        // 返回最终的树形结构
        return new ArrayList<>(provinceMap.values());
    }

    @Override
    @Cacheable(value = "regin", key = "#root.methodName")
    public List<String> getCity() {
        return regionMapper.getCity();
    }
}
